/*
 * COMP6471 Project
 *  
 * This file is created by Yuan Tao (ewan.msn@gmail.com)
 * Licensed under GNU GPL v3
 * 
 * $Author: ewan.msn@gmail.com $
 * $Date: 2011-11-16 06:13:08 +0000 (Wed, 16 Nov 2011) $
 * $Rev: 60 $
 * $HeadURL: http://comp6471.googlecode.com/svn/Project5/src/kklib/UIControllerFacade.java $
 * 
 */

package kklib;

import java.util.ArrayList;
import java.util.Observable;
import java.util.StringTokenizer;

import utils.SysLogger;



// handle all UI request. Singleton Instance & Observable.
public class UIControllerFacade extends Observable {
	private static UIControllerFacade instance;		// Singleton instance.
	
	private Layout layout = null;
	
	public static synchronized UIControllerFacade getInstance() {
		if (instance == null) {
			instance = new UIControllerFacade();
		}
		return instance;
	}
	
	// the user select a game
	public int chooseAGame(ArrayList<Layout> layouts, int gameNo) {
		if (gameNo < 0 || gameNo >= layouts.size()) {
			return -1;
		}
		layout = layouts.get(gameNo - 1);
		notifyAllObservers();
		
		return 0;
	}
	
	// set value/ possible value to cells.
	private int setValues(String values, int type) {
		StringTokenizer st = new StringTokenizer(values); 
		int cnt = st.countTokens();
		if (cnt < 1) {
			return 2;		// empty line
		}
		
		while (cnt-- > 0) {
			String token = st.nextToken();
			
			// check correction of  input value
			if (token.length() != 4) {				
				return 2;		// input error. Game size must be < 10
			}
			
			char ch = token.charAt(0);
			
			if (ch < 'A' || ch > 'A' + layout.gameSize - 1) {
				return 2;		// input error
			}
			ch = token.charAt(1);
			if (ch < '1' || ch > '1' + layout.gameSize - 1) {
				return 2;		// input error
			}
			
			int val = 0;
			
			try {
				val = Integer.parseInt(token.substring(3));
			} catch (NumberFormatException e) {
				return 2;
			}			
			
			// set the value to cell
			if (layout.setCellValue(token.substring(0, 2), val, type) != 0) {
				SysLogger.err("setCellValue. " + type);
				return 3;
			}				
		}		
		return 0;
	}
	
	// the user set the value for one or more cells
	public int setValuesForCells(String values) {
		int ret = setValues(values, 1);
		
		notifyAllObservers();
		if (ret != 0) {
			return ret;
		}
		return layout.checkSolution();
	}

	// the user set the possible value for one or more cells
	public int setPossibleValuesForCells(String values) {
		int ret = setValues(values, 0);
		
		notifyAllObservers();
		return ret;
	}
	
	// refresh the UI
	public void notifyAllObservers() {
		setChanged();
		notifyObservers(layout);
	}

}
